<template>
  <div class="medical-upload-container">
    <div class="upload-card">
      <div class="upload-header">
        <h3>眼底影像分析</h3>
        <el-tag type="success">AI辅助诊断系统</el-tag>
      </div>
      <el-upload
        action="#"
        :auto-upload="false"
        list-type="picture-card"
        :on-change="handleFileChange"
        :on-remove="handleFileRemove"
        :before-upload="beforeUpload"
        :file-list="selectedFiles"
        :limit="16"
        multiple
        class="medical-upload"
      >
        <i class="el-icon-plus medical-upload-add"></i>
        <template #tip>
          <div class="upload-tips">
            <el-icon><InfoFilled></InfoFilled></el-icon>
            请上传清晰的眼底照片（支持JPG/PNG格式，单张≤1MB）
          </div>
        </template>
      </el-upload>
      <!--图片预览-->
      <div class="image-grid">
        <div
          v-for="(file, index) in selectedFiles"
          :key="`${file.name}-${index}`"
          class="image-card"
          :class="{
            'highlight-left': index % 2 === 0,
            'highlight-right': index % 2 === 1,
          }"
        >
          <div class="eye-tag">{{ index % 2 === 0 ? "左眼" : "右眼" }}</div>
          <img :src="file.url" class="preview-image" alt="file.name" />
          <div class="image-footer">
            <span class="file-name">{{ file.name }}</span>
            <el-icon v-if="file.status === 'fail'" class="error-icon">
              <CircleCloseFilled></CircleCloseFilled>
            </el-icon>
          </div>
        </div>
      </div>
      <el-button
        type="primary"
        class="analysis-btn"
        @click="handleUpload"
        :disabled="selectedFiles.length === 0"
      >
        <el-icon><UploadFilled></UploadFilled></el-icon>
        开始AI分析
      </el-button>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  InfoFilled,
  CircleCloseFilled,
  UploadFilled,
} from "@element-plus/icons-vue";
import { ref, getCurrentInstance } from "vue";
const instance = getCurrentInstance();
const proxy = instance?.proxy as any;
import { useImageStore } from "@/stores/imageStore";
import { UploadFile, UploadProps } from "element-plus";
const store = useImageStore();

const emit = defineEmits(["upload-success"]);
const selectedFiles = ref<UploadFile[]>([]);

//文件选择
const handleFileChange: UploadProps["onChange"] = (_: any, fileList) => {
  //过滤无效文件
  selectedFiles.value = (fileList as UploadFile[])
    .filter((f): f is UploadFile & { raw: File } => !!f.raw)
    .map((f) => ({
      ...f,
      name: f.name,
      status: f.status || "ready",
      url: URL.createObjectURL(f.raw), // 预览地址
      raw: f.raw,
    }));
};
//文件移除
const handleFileRemove: UploadProps["onRemove"] = (_: any, fileList) => {
  //更新列表，过滤
  selectedFiles.value = (fileList as UploadFile[])
    .filter((f): f is UploadFile & { raw: File } => !!f.raw)
    .map((f) => ({
      ...f,
      url: f.url || URL.createObjectURL(f.raw),
      raw: f.raw,
    }));
};

//上传前校验
const beforeUpload: UploadProps["beforeUpload"] = (file) => {
  const isLt1M = file.size / 1024 / 1024 < 1;
  if (!isLt1M) {
    proxy.message.error("上传图片大小不能超过1MB");
  }
  //限制图片
  const isImage = file.type.startsWith("image/");
  if (!isImage) {
    proxy.message.error("请上传图片格式文件");
  }
  return isLt1M && isImage;
};

//上传分析
const handleUpload = async () => {
  if (selectedFiles.value.length === 0) {
    proxy.message.error("请先上传图片");
    return;
  }
  //分离左右眼
  const leftImages: File[] = [];
  const rightImages: File[] = [];

  selectedFiles.value.forEach((file, index) => {
    if (index % 2 === 0) {
      leftImages.push(file.raw as File);
    } else {
      rightImages.push(file.raw as File);
    }
  });
  //是否同时有左右眼
  if (leftImages.length === 0 || rightImages.length === 0) {
    proxy.message.error("请至少上传一张左眼和一张右眼图片");
    return;
  }
  //请求
  try {
    await store.guestAnalyze(leftImages, rightImages);
    proxy.message.success("图片上传成功");
    //清空选中的文件
    selectedFiles.value = [];
    emit("upload-success");
  } catch (error) {
    proxy.message.error("图片上传失败");
    selectedFiles.value = selectedFiles.value.map((f) => ({
      ...f,
      status: "fail",
    }));
  }
};
</script>

<style scoped>
.medical-upload-container {
  padding: 24px;
  background: #f5f7fb;
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  overflow: auto;
}

.upload-card {
  background: white;
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  padding: 24px;
  width: 100%;
  max-width: 1200px;
  height: calc(100vh - 48px); /* 适应浏览器窗口高度 */
  overflow: auto;
}

.upload-header {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 24px;
  border-bottom: 1px solid #e4e7ed;
  padding-bottom: 16px;
}

.upload-header h3 {
  margin: 0;
  color: #1a2d6d;
  font-size: 20px;
}

.medical-upload :deep(.el-upload) {
  border: 2px dashed #409eff;
  border-radius: 8px;
  transition: all 0.3s;
}

.medical-upload :deep(.el-upload:hover) {
  border-color: #1a2d6d;
  transform: translateY(-2px);
}

.medical-upload-add {
  font-size: 28px;
  color: #409eff;
}

.upload-tips {
  color: #909399;
  font-size: 14px;
  margin-top: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.image-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 24px;
  margin: 24px 0;
}

.image-card {
  border: 1px solid #e4e7ed;
  border-radius: 8px;
  overflow: hidden;
  position: relative;
  transition: all 0.3s;
}

.image-card:hover {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  transform: translateY(-2px);
}

.highlight-left {
  border-left: 4px solid #409eff;
}

.highlight-right {
  border-left: 4px solid #67c23a;
}

.eye-tag {
  position: absolute;
  top: 8px;
  left: 8px;
  background: rgba(64, 158, 255, 0.9);
  color: white;
  padding: 4px 12px;
  border-radius: 4px;
  font-size: 12px;
  z-index: 1;
}

.preview-image {
  width: 100%;
  height: 200px;
  object-fit: contain;
  background: #f8f9fa;
}

.image-footer {
  padding: 12px;
  background: #f8f9fa;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.file-name {
  font-size: 12px;
  color: #606266;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
}

.error-icon {
  color: #f56c6c;
  margin-left: 8px;
}

.analysis-btn {
  width: 100%;
  height: 48px;
  font-size: 16px;
  letter-spacing: 1px;
}
</style>
